package com.molichuxing.services.infrastructure.service.impl;

import com.molichuxing.framework.dto.Paged;
import com.molichuxing.framework.utils.ObjectCastUtil;
import com.molichuxing.services.infrastructure.bean.EnterpriseBean;
import com.molichuxing.services.infrastructure.convertor.Convert;
import com.molichuxing.services.infrastructure.dao.EnterpriseMapper;
import com.molichuxing.services.infrastructure.dto.request.create.OrderEnterpriseCreateDto;
import com.molichuxing.services.infrastructure.dto.response.OrderEnterpriseDto;
import com.molichuxing.services.infrastructure.service.OrderEnterpriseService;
import com.molichuxing.services.property.EnterpriseStateEnum;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.util.*;

/**
 * 企业订单
 *
 * @Author zoumingyu
 * @Date 2020年06月04日
 */
@Service("orderEnterpriseService")
public class OrderEnterpriseServiceImpl implements OrderEnterpriseService {
    private static final Logger logger = LoggerFactory.getLogger(OrderEnterpriseServiceImpl.class);

    @Resource
    private EnterpriseMapper enterpriseMapper;

    /**
     * 获取企业订单
     *
     * @param orderCode 订单号
     * @return
     */
    @Override
    public OrderEnterpriseDto getEnterprise(Long orderCode) {
        return Convert.toEnterpriseDto(enterpriseMapper.getByOrderCode(orderCode));
    }

    /**
     * 获取企业订单
     *
     * @param orderCodes 订单号list
     * @return
     */
    @Override
    public List<OrderEnterpriseDto> getEnterpriseList(List<Long> orderCodes) {
        if (orderCodes == null || orderCodes.isEmpty()) {
            return null;
        } else if (orderCodes.size() == 1) {
            return Arrays.asList(getEnterprise(orderCodes.get(0)));
        }

        return Convert.toOrderEnterpriseDto(enterpriseMapper.getEnterpriseListByOrderCodes(orderCodes));
    }

    /**
     * 获取企业订单
     *
     * @param orderCodes 订单号list
     * @return
     */
    @Override
    public Map<Long, OrderEnterpriseDto> getEnterpriseMap(List<Long> orderCodes) {
        List<OrderEnterpriseDto> list = getEnterpriseList(orderCodes);
        if (list == null || list.isEmpty()) {
            return null;
        }

        Map<Long, OrderEnterpriseDto> result = new HashMap<>();
        list.forEach(dto -> {
            result.put(dto.getOrderCode(), dto);
        });

        return result;
    }

    /**
     * 存在企业订单信息
     *
     * @param createDto
     * @return Integer 企业订单id
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, timeout = 36000, rollbackFor = Exception.class)
    public Integer create(OrderEnterpriseCreateDto createDto) {
        EnterpriseBean bean = Convert.toEnterpriseBean(createDto);
        enterpriseMapper.create(bean);
        return bean.getId();
    }

    /**
     * 续订修改主订单
     *
     * @param orderCode 订单号
     * @return
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, timeout = 36000, rollbackFor = Exception.class)
    public boolean modifyHaveSuborder(Long orderCode) {
        return enterpriseMapper.modifyHaveSuborder(orderCode, true) > 0 ? true : false;
    }

    /**
     * 修改订单状态
     *
     * @param orderCode 订单号
     * @param oldState  旧状态
     * @param newState  新状态
     * @return
     */
    @Override
    public boolean modifyState(Long orderCode, EnterpriseStateEnum oldState, EnterpriseStateEnum newState) {
        return enterpriseMapper.modifyState(orderCode, oldState.getValue(), newState.getValue()) > 0 ? true : false;
    }

    @Override
    public List<OrderEnterpriseDto> listOrderEnterpriseByDay(List<Integer> dayInt, LocalDate localDate) {
        return Convert.toOrderEnterpriseDto(enterpriseMapper.listOrderEnterpriseByDay(dayInt, localDate));
    }


    /**
     * 获取数量
     *
     * @param params
     * @return
     */
    @Override
    public Integer getCount(Map<String, Object> params) {
        long total = enterpriseMapper.getPageCount(params);
        int res = Integer.parseInt(total + "");
        return res;
    }

    /**
     * 分页获取专属里程订单信息
     *
     * @param params   listType：列表类型-enum <br/>
     *                 orderStatus：订单状态-enum <br/>
     *                 orderCode：订单号-long <br/>
     *                 userIds：用户id-list <br/>
     *                 storeIds：门店id-list <br/>
     *                 orderTimeStart：下单开始时间-LocalDateTime <br/>
     *                 orderTimeEnd：下单结束时间-LocalDateTime
     * @param pageNum  页数
     * @param pageSize 每页条数
     * @return
     * @throws Exception
     */
    @Override
    public Paged<OrderEnterpriseDto> getOrderList(Map<String, Object> params, int pageNum, int pageSize)
            throws Exception {
        // 拼接条件
        EnterpriseStateEnum orderStatusEnum = null;
        if (params.get("state") != null) {
            orderStatusEnum = EnterpriseStateEnum.getEnum(Integer.parseInt(params.get("state").toString()));
            params.put("state", orderStatusEnum.getValue());
        }

        params.put("enterpriseId", ObjectCastUtil.castString(params.get("enterpriseId")));

        params.put("orderCode", ObjectCastUtil.castString(params.get("orderCode")));

        if (orderStatusEnum != null) {
            switch (orderStatusEnum) {
                case DELIVERY:
                    // 起租日开始时间-LocalDateTime
                    params.put("leaseInceptionStart", ObjectCastUtil.castLocalDateTimeStart(params.get("leaseInceptionStart")));
                    // 起租日结束时间-LocalDateTime
                    params.put("leaseInceptionEnd", ObjectCastUtil.castLocalDateTimeEnd(params.get("leaseInceptionEnd")));
                    // 租赁截止日开始时间-LocalDateTime
                    params.put("leaseExpireStart", ObjectCastUtil.castLocalDateTimeStart(params.get("leaseExpireStart")));
                    // 租赁截止日结束时间-LocalDateTime
                    params.put("leaseExpireEnd", ObjectCastUtil.castLocalDateTimeEnd(params.get("leaseExpireEnd")));
                    break;
                case UNDELIVERY:
                case UNPAID:
                case UNHIRE:
                default:
                    // 下单开始时间-LocalDateTime
                    params.put("gmtCreateStart", ObjectCastUtil.castLocalDateTimeStart(params.get("gmtCreateStart")));
                    // 下单结束时间-LocalDateTime
                    params.put("gmtCreateEnd", ObjectCastUtil.castLocalDateTimeEnd(params.get("gmtCreateEnd")));
                    break;
            }
        } else {
            // 下单开始时间-LocalDateTime
            params.put("gmtCreateStart", ObjectCastUtil.castLocalDateTimeStart(params.get("gmtCreateStart")));
            // 下单结束时间-LocalDateTime
            params.put("gmtCreateEnd", ObjectCastUtil.castLocalDateTimeEnd(params.get("gmtCreateEnd")));
        }


        long total = enterpriseMapper.getPageCount(params);
        List<EnterpriseBean> page = null;
        if (total > 0) {
            page = enterpriseMapper.getPage(params, pageNum, pageSize);
        }

        return new Paged<OrderEnterpriseDto>(Convert.toOrderEnterpriseDto(page), total, pageSize);

    }

    /**
     * 根据企业ID获取订单信息
     *
     * @param enterpriseId
     * @return
     */
    @Override
    public List<OrderEnterpriseDto> getByEnterpriseId(Integer enterpriseId) {
        List<OrderEnterpriseDto> res = new ArrayList<>();
        List<EnterpriseBean> list = enterpriseMapper.getByEnterpriseId(enterpriseId);
        if (list != null && list.size() > 0) {
            for (EnterpriseBean bean : list) {
                if (bean != null) {
                    OrderEnterpriseDto dto = Convert.toEnterpriseDto(bean);
                    res.add(dto);
                }
            }
        }
        return res;
    }

    /**
     * 根据时间获取订单号
     *
     * @param params
     * @return
     */
    @Override
    public Set<Long> getByDate(Map<String, Object> params) {
        Set<Long> res = new HashSet<>();
        List<EnterpriseBean> list = enterpriseMapper.getByDate(params);
        if (list != null && list.size() > 0) {
            for (EnterpriseBean bean : list) {
                if (bean != null && bean.getOrderCode() != null) {
                    res.add(bean.getOrderCode());
                }
            }
        }
        return res;
    }

    @Override
    public Map<Long, Long> getOrderCodeByParentOrderCodes(List<Long> enterpriseOrderCodes) {
        List<EnterpriseBean> list = enterpriseMapper.getByParendCodes(enterpriseOrderCodes);
        Map<Long, Long> map = new HashMap<>();
        if (list != null && list.size() > 0) {
            for (EnterpriseBean bean : list) {
                if (bean != null && bean.getPrentOrderCode() != null && bean.getOrderCode() != null) {
                    map.put(bean.getPrentOrderCode(), bean.getOrderCode());
                }
            }
        }
        return map;
    }

    /**
     * 查询到期订单
     *
     * @param leaseExpire 到期时间
     * @return
     */
    @Override
    public List<OrderEnterpriseDto> getExpire(LocalDate leaseExpire) {
        return Convert.toOrderEnterpriseDto(enterpriseMapper.getExpire(leaseExpire));
    }

    /**
     * 查询企业订单信息
     *
     * @param parentOrderCode 父订单号
     * @return
     */
    @Override
    public OrderEnterpriseDto getEnterpriseByParentOrderCode(Long parentOrderCode) {
        return Convert.toEnterpriseDto(enterpriseMapper.getEnterpriseByParentOrderCode(parentOrderCode));
    }

    /**
     * 获取续订单信息
     *
     * @param leaseInception 起租日
     * @return
     */
    @Override
    public List<OrderEnterpriseDto> getRenewLease(LocalDate leaseInception) {
        return Convert.toOrderEnterpriseDto(enterpriseMapper.getRenewLease(leaseInception, EnterpriseStateEnum.UNHIRE.getValue()));
    }

    @Override
    public Integer modifyLeaseConfirm(Long orderCode, Integer oldState, Integer newState, LocalDate leaseInceptio, LocalDate leaseExpire) {
        return enterpriseMapper.modifyLeaseConfirm(orderCode, oldState, newState, leaseInceptio, leaseExpire);
    }

}
